added samples
[windows-sources.git] / sdk / samples / all in on code / Visual Studio 2008 / VBAutomateWord / ReadMe.txt
blobe2e2e7f7c3c62cb8145101e2f875bdb726b586b1
1 ========================================================================
2     CONSOLE APPLICATION : VBAutomateWord Project Overview
3 ========================================================================
5 /////////////////////////////////////////////////////////////////////////////
6 Summary:
8 The VBAutomateWord example demonstrates the use of Visual Basic.NET codes to 
9 create a Microsoft Word instance, create a new document, insert a paragraph 
10 and a table, save the document, close the Microsoft Word application and then 
11 clean up unmanaged COM resources.
13 Office automation is based on Component Object Model (COM). When you call a 
14 COM object of Office from managed code, a Runtime Callable Wrapper (RCW) is 
15 automatically created. The RCW marshals calls between the .NET application 
16 and the COM object. The RCW keeps a reference count on the COM object. If 
17 all references have not been released on the RCW, the COM object of Office 
18 does not quit and may cause the Office application not to quit after your 
19 automation. In order to make sure that the Office application quits cleanly, 
20 the sample demonstrates two solutions.
22 Solution1.AutomateWord demonstrates automating Microsoft Word application by 
23 using Microsoft Word Primary Interop Assembly (PIA) and explicitly assigning 
24 each COM accessor object to a new varaible that you would explicitly call 
25 Marshal.FinalReleaseComObject to release it at the end.
27 Solution2.AutomateWord demonstrates automating Microsoft Word application by 
28 using Microsoft Word PIA and forcing a garbage collection as soon as the 
29 automation function is off the stack (at which point the RCW objects are no 
30 longer rooted) to clean up RCWs and release COM objects.
33 /////////////////////////////////////////////////////////////////////////////
34 Prerequisite:
36 You must run this code sample on a computer that has Microsoft Word 2007 
37 installed.
40 /////////////////////////////////////////////////////////////////////////////
41 Demo:
43 The following steps walk through a demonstration of the Word automation 
44 sample that starts a Microsoft Word instance, creates a new document, 
45 inserts a paragraph and a table, saves the document, and quits the Microsoft 
46 Word application cleanly.
48 Step1. After you successfully build the sample project in Visual Studio 2008, 
49 you will get the application: VBAutomateWord.exe.
51 Step2. Open Windows Task Manager (Ctrl+Shift+Esc) to confirm that no 
52 winword.exe is running. 
54 Step3. Run the application. It should print the following content in the 
55 console window if no error is thrown.
57   Word.Application is started
58   A new document is created
59   Insert a paragraph
60   Save and close the document
61   Quit the Word application
63   Word.Application is started
64   Insert a paragraph
65   Insert a table
66   Save and close the document
67   Quit the Word application
69 Then, you will see two new documents in the directory of the application: 
70 Sample1.docx and Sample2.docx. Both documents have the following content.
72   Heading 1
74 Sample2.docx additionally has this table in the document.
76   r1c1  r1c2
77   r2c1  r2c2
78   r3c1  r3c2
79   r4c1  r4c2
80   r5c1  r5c2
82 Step4. In Windows Task Manager, confirm that the winword.exe process does not 
83 exist, i.e. the Microsoft Word intance was closed and cleaned up properly.
86 /////////////////////////////////////////////////////////////////////////////
87 Project Relation:
89 VBAutomateWord - CSAutomateWord - CppAutomateWord
91 These examples automate Microsoft Word to do the same thing in different 
92 programming languages.
95 /////////////////////////////////////////////////////////////////////////////
96 Creation:
98 Step1. Create a Console application and reference the Word Primary Interop 
99 Assembly (PIA). To reference the Word PIA, right-click the project file
100 and click the "Add Reference..." button. In the Add Reference dialog, 
101 navigate to the .NET tab, find Microsoft.Office.Interop.Word 12.0.0.0 and 
102 click OK.
104 Step2. Import and rename the Excel interop namepace:
106         Imports Word = Microsoft.Office.Interop.Word
108 Step3. Start up a Word application by creating a Word.Application object.
110         oWord = New Word.Application()
112 Step4. Get the Documents collection from Application.Documents and call its 
113 Add function to create a new document. The Add function returns a Document 
114 object.
116 Step5. Insert a paragraph.
118         oParas = oDoc.Paragraphs
119         oPara = oParas.Add()
120         oParaRng = oPara.Range
121         oParaRng.Text = "Heading 1"
122         oFont = oParaRng.Font
123         oFont.Bold = 1
124         oParaRng.InsertParagraphAfter()
126 Step6. Insert a table.
128 The following code has the problem that it invokes accessors which will also 
129 create RCWs and reference them. For example, calling Document.Bookmarks.Item 
130 creates an RCW for the Bookmarks object. If you invoke these accessors via 
131 tunneling as this code does, the RCWs are created on the GC heap, but the 
132 references are created under the hood on the stack and are then discarded. As 
133 such, there is no way to call MarshalFinalReleaseComObject on those RCWs. To 
134 get them to release, you would either need to force a garbage collection as 
135 soon as the calling function is off the stack (at which point these objects 
136 are no longer rooted) and then call GC.WaitForPendingFinalizers, or you would 
137 need to change the syntax to explicitly assign these accessor objects to a 
138 variable that you would then explicitly call Marshal.FinalReleaseComObject on. 
140         oBookmarkRng = oDoc.Bookmarks.Item("\endofdoc").Range
142         oTable = oDoc.Tables.Add(oBookmarkRng, 5, 2)
143         oTable.Range.ParagraphFormat.SpaceAfter = 6
145         For r As Integer = 1 To 5
146                 For c As Integer = 1 To 2
147                         oTable.Cell(r, c).Range.Text = "r" & r & "c" & c
148                 Next
149         Next
151         ' Change width of columns 1 & 2
152         oTable.Columns(1).Width = oWord.InchesToPoints(2)
153         oTable.Columns(2).Width = oWord.InchesToPoints(3)
155 Step7. Save the document as a docx file and close it.
157         Dim fileName As String = Path.GetDirectoryName( _
158         Assembly.GetExecutingAssembly().Location) & "\Sample1.docx"
159         oDoc.SaveAs(fileName, Word.WdSaveFormat.wdFormatXMLDocument)
160         oDoc.Close()
162 Step8. Quit the Word application.
164         oWord.Quit(False)
166 Step9. Clean up the unmanaged COM resource. To get Word terminated rightly, 
167 we need to call Marshal.FinalReleaseComObject() on each COM object we used.
168 We can either explicitly call Marshal.FinalReleaseComObject on all accessor 
169 objects:
171         ' See Solution1.AutomateWord
172         If Not oFont Is Nothing Then
173                 Marshal.FinalReleaseComObject(oFont)
174                 oFont = Nothing
175         End If
176         If Not oParaRng Is Nothing Then
177                 Marshal.FinalReleaseComObject(oParaRng)
178                 oParaRng = Nothing
179         End If
180         If Not oPara Is Nothing Then
181                 Marshal.FinalReleaseComObject(oPara)
182                 oPara = Nothing
183         End If
184         If Not oParas Is Nothing Then
185                 Marshal.FinalReleaseComObject(oParas)
186                 oParas = Nothing
187         End If
188         If Not oDoc Is Nothing Then
189                 Marshal.FinalReleaseComObject(oDoc)
190                 oDoc = Nothing
191         End If
192         If Not oDocs Is Nothing Then
193                 Marshal.FinalReleaseComObject(oDocs)
194                 oDocs = Nothing
195         End If
196         If Not oWord Is Nothing Then
197                 Marshal.FinalReleaseComObject(oWord)
198                 oWord = Nothing
199         End If
201 and/or force a garbage collection as soon as the calling function is off the 
202 stack (at which point these objects are no longer rooted) and then call 
203 GC.WaitForPendingFinalizers.
205         ' See Solution2.AutomateWord
206         GC.Collect()
207         GC.WaitForPendingFinalizers()
208         ' GC needs to be called twice in order to get the Finalizers called 
209         ' - the first time in, it simply makes a list of what is to be 
210         ' finalized, the second time in, it actually is finalizing. Only 
211         ' then will the object do its automatic ReleaseComObject.
212         GC.Collect()
213         GC.WaitForPendingFinalizers()
216 /////////////////////////////////////////////////////////////////////////////
217 References:
219 MSDN: Word 2007 Developer Reference
220 http://msdn.microsoft.com/en-us/library/bb244391.aspx
222 How to automate Word from Visual Basic .NET to create a new document
223 http://support.microsoft.com/kb/316383/
226 /////////////////////////////////////////////////////////////////////////////